# Author: Chris Moyer
# Report Generation tools
from resources.ticket import Ticket
from resources.comment import Comment
from resources.project import Project
from marajo.appengine.api.users import User

from boto.sdb.db.query import Query
import csv

class ReportGenerator(object):
    """
    Report Generator
    This creates a report that can be
    returned as reStructuredText, or HTML
    Author: Chris Moyer
    """

    def __init__(self, query):
        """
        Report based on this query

        @param query: the query to use
        @type query: boto.sdb.db.query.Query
        """
        assert(isinstance(query, Query))
        self.query = query
        self.objects = [k for k in query]

    def dumps(self):
        print "========================"
        for i in self.objects:
            print i
        print "========================"

    def as_csv(self):
        from tempfile import TemporaryFile
        f = TemporaryFile()
        out = csv.writer(f)
        props = []
        for prop in self.objects[0].properties():
            if prop.name:
                props.append(prop.name)
        out.writerow(props)

        f.seek(0)
        print f.read()

    def project_work_report(self, project=None):
        """
        This generates a report separated by project, and
        then split by user

        @param project: Project to limit to. If not specified, this will loop through ALL projects
        """
        if not project:
            ret = {}
            for p in Project.all():
                ret[p.name] = self.project_work_report(project=p)
            return ret
        else:
            ret = {}
            total = 0
            for u in User.all():
                ret[u.username] = self._hours(project=project, user=u)
                total += ret[u.username]
            ret["__total__"] = total
            return ret

    def user_work_report(self,user=None):
        """
        This Generates a report separated first by user, and
        then split by project
        """
        if not user:
            ret = {}
            for u in User.all():
                ret[u.username] = self.user_work_report(user=u)
            return ret
        else:
            ret = {}
            for p in Project.all():
                ret[p.name] = self._hours(project=project, user=user)
            return ret


    def _hours(self, project=None, release=None, user=None, start_date=None, end_date=None):
        """
        Get the number of hours spent

        @param project: Optional, project to limit to
        @param release: Optional, the release to limit to. Note, this should not be used in conjunction witht he Project option
        @param user: Optional, user to limit to
        @param start_date: Optional, Limit the start date
        @param end_date: Optional, Limit the end date
        """
        query = Comment.find()
        if release:
            query.filter("release =", release)
        if user:
            query.filter("owner =", user)
        if start_date:
            query.filter("date >", start_date)
        if end_date:
            query.filter("date <", end_date)

        hours = 0
        for c in query:
            if not project or c.ticket.project.id == project.id:
                hours += c.hours

        return hours
